package com.elecbook.auth.controller;

import com.alibaba.fastjson.JSON;

import com.elecbook.auth.config.authsecurity.WxLoginUsernamePasswordAuthenticationToken;
import com.elecbook.auth.config.properties.OauthServerProperties;
import com.elecbook.auth.model.dto.LoginDTO;
import com.elecbook.base.exception.BaseInfoException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.OAuth2Request;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

@RestController
@RequestMapping("/customLogin")
public class LoginController {

    @Autowired
    AuthenticationManager authenticationManager;

    @Resource(name = "authorizationServerTokenServicesCustom")
    private AuthorizationServerTokenServices authorizationServerTokenServices;

    @Autowired
    OauthServerProperties oauthServerProperties;

    /**
     * description 来自源码的函数（复制的）
     * @author zken
     * @CreateDate 2024/11/11 20:25:53
     */
    private ResponseEntity<OAuth2AccessToken> getResponse(OAuth2AccessToken accessToken) {
        HttpHeaders headers = new HttpHeaders();
        headers.set("Cache-Control", "no-store");
        headers.set("Pragma", "no-cache");
        headers.set("Content-Type", "application/json;charset=UTF-8");
        return new ResponseEntity<OAuth2AccessToken>(accessToken, headers, HttpStatus.OK);
    }

    /**
     * description 微信登录接口
     *
     * @author zken
     * CreateDate 2024/11/2 21:54:36
     */
    // MARK 调用tokenService方法，返回对应的jwt
    @PostMapping("/wxlogin")
    public ResponseEntity<OAuth2AccessToken> wxlogin(@RequestBody LoginDTO loginDTO) {
        // 需要预先换取openId
        String loginDtoStr = JSON.toJSONString(loginDTO);
        OAuth2AccessToken token = null;
        try {
            // 将username参数填写为code进行发送请求
            WxLoginUsernamePasswordAuthenticationToken auth = new WxLoginUsernamePasswordAuthenticationToken(loginDtoStr, null);
            Authentication authentication = authenticationManager.authenticate(auth);
            System.out.println(authentication.getPrincipal());

            // 测试构造一个oauthrequest
            // 构造一个请求参数
            Map<String, String> requestParams = new HashMap<>();
            requestParams.put("client_id", "client");
            requestParams.put("scope", "all");
            //  设置一个请求id，实际上，这个是需要上传的
            String clientId = "client";
            // 设置一个资源范围，在本项目中，使用的是配置中注入的资源的id来进行配置
            Set<String> resourceIds = new HashSet<>(oauthServerProperties.getResourceIds());
            // 设置一个scope范围
            Set<String> scopes = new HashSet<>();
            scopes.add("all");

            OAuth2Request oAuth2Request = new OAuth2Request(
                    requestParams,
                    clientId,
                    authentication.getAuthorities(),
                    true, // 默认设置为true即可
                    scopes,
                    resourceIds,
                    null,
                    null,
                    null);
            OAuth2Authentication oAuth2Authentication = new OAuth2Authentication(oAuth2Request, authentication);
            token = authorizationServerTokenServices.createAccessToken(oAuth2Authentication);
        } catch (Exception e) {
            e.printStackTrace(System.err);
            throw new BaseInfoException("错误的登录");
        }
        return getResponse(token);
    }
}
